/**
 *资源和游戏加载器  
 * 
 */
package com.mj
{
	import com.adobe.serialization.json.JSON;
	
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.external.ExternalInterface;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.profiler.showRedrawRegions;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.Security;
	import flash.system.SecurityDomain;
	import flash.text.TextField;
	import flash.utils.Dictionary;
	import flash.utils.clearInterval;
	import flash.utils.clearTimeout;
	import flash.utils.setInterval;
	import flash.utils.setTimeout;
	
	import com.mj.ASDebugger;
	
	import resLib.loaderes.ResLoader;
	import resLib.version.VersionManager;
	
	import utils.core.ContexMenuManager;
	
	
	

	[SWF(width="750",height="650", backgroundColor="0x000000")]

	public class mjLoader extends Sprite
	{
		private const cdnPath:String = "http://";//cdn地址
		private const checkCDNAvailableFile:String = "show_version.txt";//检测cdn可用的文件
		private const versionFileName:String = "advanceConfig.txt";//版本号配置文件
		private const projectName:String = "mj";
		
		private var loader:Loader;
		private var gameContainer:Sprite;
		private var loading:MovieClip;
		private var logoLoader:Loader;
		private var logo:Bitmap;
		private var lessTryLoadNum:uint;
		private var _lessModule:int;
		private var _moduleDic:Dictionary;
		private var _urlLoaderDic:Dictionary;
		private var _moduleLoadedDic:Dictionary;//每个model的当前加载量
		private var _totalSize:uint;//总资源大小，单位k
		private var _maxThreadNum:uint;//最大同时加载线程数
		private var _loadingArr:Array;
		private var _totalLoadArr:Array;
		private var loadingLoader:Loader;
		
		private var _gameMainLoaderInfo:LoaderInfo;
		private var countLoadedHandle:uint;
		private var _prePath:String;
		private var _lastLoaded:Number;
		private var _noLoadDataCount:int;
		
		public function mjLoader()
		{
			super();
			ASDebugger.debug("---Mainloader构造");
			flash.system.Security.allowDomain("*");
			_lastLoaded = 0;
			_noLoadDataCount = 0;
			
			if(cdnPath.indexOf("imgcache.qzoneapp.com") == -1)
			{
				ASDebugger.debug("！警告！，没有链接到腾讯CDN");
				ASDebugger.debug("");
			}
			
			_moduleDic = new Dictionary();
			_urlLoaderDic = new Dictionary();
			_moduleLoadedDic = new Dictionary();
			lessTryLoadNum = 500;
			_maxThreadNum = 2//3; 
			_loadingArr = [];
			gameContainer = new Sprite();
			this.addChild(gameContainer);
			this.addEventListener(Event.ADDED_TO_STAGE, added);
			
		}
		
		private function added(evt:Event):void
		{
			
			ASDebugger.debug("---Mainloader.swf初始化");
			stage.align = StageAlign.TOP_LEFT//.TOP;
			stage.scaleMode = StageScaleMode.NO_SCALE; 
			stage.frameRate =24;
			stage.stageFocusRect = false;
			this.removeEventListener(Event.ADDED_TO_STAGE, added);
			VersionManager.ini(projectName, checkCDNAvailableFile, versionFileName, cdnPath, stage.loaderInfo.url, ini);
		}
		
		private function ini():void
		{
			ContexMenuManager.addItem(this,"版本号："+VersionManager.showVersion);
			
			if(VersionManager.useCDN && VersionManager.isCDNAvailable)
			{
				ASDebugger.debug("---CDN可用");
				_prePath = cdnPath;//cdn地址
			}
			else
			{
				ASDebugger.debug("---CDN不可用");
				_prePath = "";
			}
				
//			ASDebugger.debug("服务器地址："+Proxy.serverURL);
//			ASDebugger.debug("web请求地址："+stage.loaderInfo.url);
			_lessModule = VersionManager.versionFileData.modules.length;
			
			_totalLoadArr = [];
			for each(var module:Object in VersionManager.versionFileData.modules)
			{
				_totalSize +=  module.size;
				_moduleLoadedDic[module.name] = 0;
				_totalLoadArr.push(module);
			}
			if(_maxThreadNum>_totalLoadArr.length)
			{
				_maxThreadNum = _totalLoadArr.length;
			}
			
			var loaderContext:LoaderContext = new LoaderContext();
			loaderContext.checkPolicyFile = true;
			loaderContext.applicationDomain = flash.system.ApplicationDomain.currentDomain;
			var loadingRequest:URLRequest = new URLRequest();
			loadingLoader= new Loader();
			loadingLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingLoaded);
			loadingLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadFail);
			loadingLoader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHttpStatus);
			loadingLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loadFail);
			
			loadingRequest.url = prePath + "res/loadingMc.swf?v="+VersionManager.version.MainLoading;
			loadingLoader.load(loadingRequest, loaderContext); 
			
			
			function loadFail(evt:ErrorEvent):void
			{
				evt.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, loadFail);
				evt.currentTarget.removeEventListener(Event.COMPLETE, loadingLoaded);
				evt.currentTarget.removeEventListener(HTTPStatusEvent.HTTP_STATUS, onHttpStatus);
				evt.currentTarget.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loadFail);
				loadingLoader.unloadAndStop();
				flash.utils.setTimeout(ini,800);//0.8秒后重试   
			}
			
			
			function onHttpStatus(evt:HTTPStatusEvent):void
			{
				if((loadingLoader.contentLoaderInfo.bytesLoaded<loadingLoader.contentLoaderInfo.bytesTotal) && (evt.status!=0))
				{
					loadFail(null);
				}
			}
			
			function loadingLoaded(evt:Event):void
			{
				evt.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, loadFail);
				evt.currentTarget.removeEventListener(Event.COMPLETE, loadingLoaded);
				evt.currentTarget.removeEventListener(HTTPStatusEvent.HTTP_STATUS, onHttpStatus);
				evt.currentTarget.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loadFail);
				loading = loadingLoader.content as MovieClip;  
				loading.x= 0;
				loading.y=0;
				loading.rate= 0;
//				loading.noticeTxt.mouseEnabled = false;
//				loading.noticeTxt.htmlText = setNoticeTxt(VersionManager.versionFileData.notice); 
//				loading.linkBtn.addEventListener(MouseEvent.CLICK,onLinkClick);
				function onLinkClick(evt:MouseEvent):void
				{
					//navigateToURL( new URLRequest("http://sobar.soso.com/t/87052463"), "_blank" );
				}
				addChild(loading);
				
				countLoadedHandle = flash.utils.setTimeout(countLoaded,1000);
				
				var i:uint = 0;
				while(i < _maxThreadNum)
				{
					loadNext();
					i++;
				}
					
			}
			
			function setNoticeTxt(noti:Object):String{
				var str:String = "";
				var len:int = noti.length>11?11:noti.length;
				for(var j:int =0;j<len;j++)
				{
					if(j == 0)
						str += noti[j].title +"<br>";
					else
						str += j +'、'+ noti[j].title +"<br>";
				}
				return str;
			}
			
			
		}
		
		private function refresh(data:Object=null):void
		{
			while(gameContainer.numChildren>0) 
				gameContainer.removeChildAt(0);
			ini();
		}
		
		private function loadNext():void
		{
			var isLoadOver:Boolean = false;
			var module:Object;
			if(_totalLoadArr.length > 0)
			{
				if(_loadingArr.length < _maxThreadNum)
				{
					module = _totalLoadArr.shift();
					_loadingArr.push(module);
					loadModule(module);
				}
			}
			
		}
		
		private function loadModule(module:Object):void
		{
			var moduleName:String
			var startIndex:int = 0;
			if(module.url.lastIndexOf("/") != -1)
				startIndex = module.url.lastIndexOf("/")+1;
			moduleName = module.url.substring(startIndex, module.url.lastIndexOf(".swf"));
			_moduleDic[moduleName] = module;
			var urlLoader:URLLoader;
			if(moduleName == projectName)
				urlLoader = ResLoader.loadRes(prePath + module.url, moduleName, "", onModuleLoaded, null, null, false, 1200);
//			else if(moduleName == "ContainCodeUI")
//				urlLoader = ResLoader.loadRes(module.url,  moduleName, "", onModuleLoaded, null, moduleName, true);
			else
				urlLoader = ResLoader.loadRes(prePath + module.url,  moduleName, "", onModuleLoaded, null, moduleName, true, 1200);
			if(urlLoader)
			{
				_urlLoaderDic[moduleName] = urlLoader;
				_moduleLoadedDic[moduleName] = 0;
			}
			else
			{
				_moduleLoadedDic[moduleName] = module.size*1024;
			}
		}
		
		private function onModuleLoaded(evt:Event, p:Object=null):void
		{
			_lessModule--;
//			var totalLen:int = VersionManager.versionFileData.modules.length;
//			var currentLen:int = totalLen - _lessModule;
//			loading.rate= int(currentLen*100/totalLen);
			
			var fileName:String = evt.currentTarget.loader.name;
			
			ASDebugger.debug("--完成加载："+(fileName?fileName:"") + "--剩余加载个数："+_lessModule);
			if(fileName == projectName)
			{
				_gameMainLoaderInfo = evt.currentTarget as LoaderInfo;
			}
			
//			if(_lessModule == 4)
//			{
//				VersionManager.saveAllCache();
//			}
			
			if(_lessModule < 1)
			{
				flash.utils.clearTimeout(countLoadedHandle);
				countLoadedHandle = 0;
				trace("全部加载完成了！！！！！");
				ASDebugger.debug("全部加载完成了！！！！！");
				onGameLoad();
				gameContainer.addChild(_gameMainLoaderInfo.content);//
				_gameMainLoaderInfo.loader.unloadAndStop();
//				VersionManager.saveAllCache();
				return;
			}
			
			var indexInLoadingArr:int = _loadingArr.indexOf(_moduleDic[fileName])
			if(indexInLoadingArr != -1)
			{
				_loadingArr.splice(indexInLoadingArr, 1);
			}
			delete _moduleDic[fileName];
			
			loadNext();
		}
		
		private function onGameLoad(evt:Event=null):void
		{
			loading.stop();
			this.removeChild(loading);
			loading = null;
			if(loadingLoader)
				loadingLoader.unloadAndStop();
			if(logo)
			{
				removeChild(logo);
				logo.bitmapData.dispose(); 
				logo = null;
			}
			
			for(var key:String in _urlLoaderDic)
			{
				delete _urlLoaderDic[key];
			}
			for(var moduleName:String in _moduleLoadedDic)
			{
				delete _moduleLoadedDic[moduleName];
			}
		}
		
		private function countLoaded():void
		{
			for(var moduleName:String in _urlLoaderDic)
			{
				if(_urlLoaderDic[moduleName].bytesLoaded > _moduleLoadedDic[moduleName])
					_moduleLoadedDic[moduleName] = _urlLoaderDic[moduleName].bytesLoaded;
//				else
//				{
//					ASDebugger.debug("urlLoader:"+moduleName+"的加载量减少了:"+_moduleLoadedDic[moduleName]+" >= "+_urlLoaderDic[moduleName].bytesLoaded);
//				}
			}
			var loadedSize:Number = 0;
			for each(var size:Number in _moduleLoadedDic)
			{
				loadedSize += size;
			}
			if(_lastLoaded == loadedSize)//加载数据不变
			{
				_noLoadDataCount++;
				if(_noLoadDataCount >= 180)//180秒后加载数据不变，则重新加载。
				{
					_noLoadDataCount = 0;
					ResLoader.reloadCurrentLoad();//清除当前加载的flash缓存
//					if(flash.external.ExternalInterface.available)
//						flash.external.ExternalInterface.call("freshGame");//刷新游戏
				}
			}
			else
			{
				_noLoadDataCount = 0;
				_lastLoaded = loadedSize;
			}
			loadedSize = loadedSize/1024;
			if(loading)
			{
				if(loadedSize>_totalSize)
				{
					loading.rate = 100;
				}else{
					loading.rate= int(loadedSize*100/_totalSize);
				}
			}
			
			
			if(countLoadedHandle != 0)
				countLoadedHandle = flash.utils.setTimeout(countLoaded, 1000);
		}
		
		private function setUIProgress(evt:ProgressEvent):void
		{
			_moduleLoadedDic[_moduleDic[evt.currentTarget].name] = evt.bytesLoaded;
			var loadedSize:Number = 0;
			for each(var size:Number in _moduleLoadedDic)
			{
				loadedSize += size;
			}
			loadedSize = loadedSize/1024;
			if(loadedSize>_totalSize)
			{
				loading.rate = 100;
			}else{
				loading.rate= int(loadedSize*100/_totalSize);
			}
		}
		
		public function get advanceConfig():Object
		{
			return VersionManager.versionFileData;
		}
		
		public function get prePath():String
		{
			return _prePath;
		}
	}
	
	
}